#!/bin/bash
#
# FILE: gen_lang
# LANGUAGE: bash shell script
# AUTHOR: Cody Precord
# LICENSE: wxWindows
#
# SUMMARY:
# This script is used to automate the generation of all localization files for
# every project in this repository. It can be used to create/syncronize message
# catalogs (.po/.pot) files by searching the project directories for python
# source files and running the mk18n.py script on them. The script can also be
# used for compiling all of the .po files in to Machine Object (.mo) files and
# installing them in the proper location inside the project folder.
#
# EXAMPLE USAGE:
# This script should be run from the root directory of the repository
#
# 1) Generate and Syncronize all Message Catalogs (.po)
#    ./gen_lang -p
#
# 2) Generate and Syncronize message catalogs for a specific project
#    ./gen_lang -p $FOLDERNAME
#
# 3) Compile all Machine Object (.mo) files for all projects/languages
#    ./gen_lang -m
#
# 4) Compile all .mo files for a specific project
#    ./gen_lang -m $FOLDERNAME
#
# REQUIREMENTS:
#    Bash 2.05 or Newer
#    python 2.4 or Higher
#    wxPython (any version should do)
#    msgcat, msgfmt
#    xgettext
#    msgmerge

## Editable Variables ##
APPLIST='app.fil'
SCRIPTDIR='catalogs'
LOCALEDIR='locale'

## Non Editable Variables ##
CWD=$(pwd)
EXPATH=$(dirname $0)
DOMAIN=$2
APPNAME="Gui2Exe"

# Make output pretty
BLUE="[34;01m"
CYAN="[36;01m"
GREEN="[32;01m"
RED="[31;01m"
YELLOW="[33;01m"
OFF="[0m"

### Helper Functions ###

###############################################################################
# print_help
# Print help message of available commands
###############################################################################
print_help () {
    echo "Localization Script for Generating Locale Files"
    echo "Type 'gen_lang [hmp] {Folder}' to run a build command"
    echo ""
    echo "Available Options:"
    echo "  -h      Print This help message"
    echo "  -m      Generate .mo files"
    echo "  -p      Generate .po files"
    echo ""
}


# FIXME the recursion in this sometimes causes the file paths to be wrong
###############################################################################
# generate_src_list:
#   Parameter 1: Directory to search from
#
# Recrusivly searches for source files from the given top level directory and
# appends all matches to the temporary app.fil file.
###############################################################################
generate_src_list () {
    RELPATH=$1
    for FNAME in $(ls $RELPATH); do
        if ! [ -z `echo $FNAME | grep "^.*\.py$"` ]; then
            if [ -a "$RELPATH/$FNAME" ]; then
                echo "  ${GREEN}Found${OFF}: $RELPATH/$FNAME"
                echo "$RELPATH/$FNAME" >> $APPLIST
            fi
        elif [ -d "$FNAME" ]; then
            generate_src_list "$RELPATH/$FNAME"
        else
            continue
        fi
    done
}


###############################################################################
# make_output_dirs:
#    Parameter 1: Path to look for output direcotries under
#    Postcondition: Any of the missing output directories are created
#
###############################################################################
make_output_dirs () {
    RELPATH=$1
    if ! [ -d "$SCRIPTDIR" ]; then
        echo "${CYAN}Making${OFF} $SCRIPTDIR"
        mkdir "$SCRIPTDIR"
    fi

    SRC=''
    find_pkg_dir "$RELPATH"
    local LOCDIR
    LOCDIR="$RELPATH/$LOCALEDIR"
    if ! [ -z "$SRC" ]; then
        if ! [ -d "$LOCDIR" ]; then
            echo "${CYAN}Making${OFF} $LOCDIR"
            mkdir "$LOCDIR"
        fi
    fi
}


###############################################################################
# find_pkg_dir:
#    Parameter 1: Project path to look in
#    Postcondition: SRC variable is set to value of package directory name if
#                   package is not found the value will be 0.
#
# This relies on the SRC variable being set/available in the scope of where
# this is called from. If not the there will be no way to get the results of
# this function. It also relies on the convention that the projects top level
# directory name will be the same as the package subdirectory when doing a
# case insensitive match.
#
###############################################################################
find_pkg_dir () {
    TOP=$1
    for ITEM in $(ls $TOP); do
        if [ -d "$ITEM" ]; then
            if ! [ -z `echo $ITEM | grep -i $ITEM` ]; then
                SRC="$ITEM"
                break
            fi
        fi
    done
}


###############################################################################
# do_one_build:
#    Parameter 1: Path of project to do build on
#
###############################################################################
do_one_build () {
    local WORKPATH
    WORKPATH=$1

    # Make sure output directories are available
    if [ "$BUILD_PO" -eq "1" ]; then
        echo "${CYAN}Syncronizing${OFF} Message Catalogs for ${CYAN}$WORKPATH${OFF}"
    else
        echo "${CYAN}Compiling${OFF} Machine Object files for ${CYAN}$WORKPATH${OFF}"
    fi

    echo "${CYAN}Checking${OFF} ouput directories for ${CYAN}$WORKPATH${OFF}"
    make_output_dirs "$WORKPATH"
    PO="$SCRIPTDIR"
    if [ "$BUILD_PO" -eq "1" ]; then
        echo "${CYAN}Generating${OFF} file list for ${CYAN}$WORKPATH${OFF}"
        generate_src_list "$WORKPATH"
        echo "${CYAN}Outputting${OFF} catalogs to ${GREEN}$PO${OFF}..."
        $(python mki18n.py  -pv --domain=$WORKPATH --podir=$PO) 2>/dev/null
        CLOCATION=$(pwd)
        cd $PO
        # Copy all .new files to override the originals
        for fname in $(ls); do
            if ! [ -z $(echo $fname | grep '.*\.new') ]; then
                name=$(echo $fname | sed 's/.new//')
                mv $fname $name
            fi
        done
        cd $CLOCATION
        unset CLOCATION
        echo "${RED}**${OFF} ${GREEN}Complete${OFF} ${RED}**${OFF}"
    else
        SRC=''
        MO="$WORKPATH/$LOCALEDIR"
        echo "${CYAN}Outputting${OFF} object files to ${GREEN}$MO${OFF}..."
        $(python mki18n.py  -mv --domain=$APPNAME --podir=./$PO --moTarget=$MO) 2>/dev/null
        echo "${RED}**${OFF} ${GREEN}Complete${OFF} ${RED}**${OFF}"
    fi

    # Cleanup temp files
    if [ -a messages.pot ]; then
        mv messages.pot $PO/$APPNAME.pot
    fi
    if [ -a "$APPLIST" ]; then
        rm "$APPLIST"
    fi
}


###############################################################################
# generate_files:
#   Parameter 1: Relative Directory Path
#                (Becomes the domain of the generated output file)
#   Parameter 2: 1 = Generate .po files, 0 = Generate .mo files
#   Postcondition: locale directories and po/mo files are generated/resynced
#                  with all of the python source files found under the
#                  given directory.
#
# This method uses the mk18n.py script to generate the necessary files for
# localizing a project folder. It works by checking the contents of the given
# directory and generating a temporary app.fil that contains a list of all the
# relative paths of the python files in that folder. After generating the list
# it runs the mk18n.py script to create/syncronize the DIRNAME.pot file with
# the sources and then syncronizes any .po files found in the directory with
# the new .pot file. These syncronized files will be created in a file called
# LANGUAGE.po.new. 
#
# If this is the first time this script has been run on a given directory it
# will also do the following.
#
# - po : It will create a directory called 'catalogs'. This is where the 
#        .po/.pot files will be stored.
# - mo : It will create a directory called '$SOURCEDIR/locale' that will be 
#        used for storing the compiled .mo files.
###############################################################################
generate_files () {
    WORKPATH=$1
    BUILD_PO=$2

    # If WORKPATH is empty then generate and files for all project folders
    # relative to this script
    if [ -z "$WORKPATH" ]; then
        for PROJECT in $(ls); do
            if [ -d "$PROJECT" ]; then
                echo ""
                echo "------------------------------------------------"
                echo ""
                do_one_build "$PROJECT"
            fi
        done
    else
        # TODO: Remove any trailing / from the path
        do_one_build "$WORKPATH"
    fi

}


###############################################################################
# Main
#
#
###############################################################################
# Parse command line args and set associated params
while getopts "hpm" flag
do
    if [[ "$flag" == "h" ]]; then
        print_help
        exit
    elif [[ "$flag" == "p" ]]; then
        echo "${CYAN}Starting .po file generation${OFF}"
        generate_files "$DOMAIN" 1
        exit
    elif [[ "$flag" == "m" ]]; then
        echo "${CYAN}Starting .mo file generation${OFF}"
        generate_files "$DOMAIN" 0
        exit
    else
        continue
    fi
done

# No known build options so print help and exit
print_help 
